package com.zhny.project.txt.targetset.service.impl;

import com.zhny.common.utils.DateUtils;
import com.zhny.common.utils.security.ShiroUtils;
import com.zhny.common.utils.text.Convert;
import com.zhny.project.base.range.service.ISpevalueRangeService;
import com.zhny.project.txt.dataset.domain.TxtDataset;
import com.zhny.project.txt.dataset.mapper.TxtDatasetMapper;
import com.zhny.project.txt.history.domain.TxtHistory;
import com.zhny.project.txt.history.mapper.TxtHistoryMapper;
import com.zhny.project.txt.indexset.domain.TxtIndexset;
import com.zhny.project.txt.indexset.mapper.TxtIndexsetMapper;
import com.zhny.project.txt.targetset.domain.DealQuality;
import com.zhny.project.txt.targetset.service.ITargetsetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 特征工程指标Service业务层处理
 *
 * @author yanqun
 * @date 2019-12-11
 */
@Service
public class TargetsetServiceImpl implements ITargetsetService {
    @Autowired
    private TxtIndexsetMapper txtIndexsetMapper;
    @Autowired
    private TxtDatasetMapper txtDatasetMapper;
    @Autowired
    private ISpevalueRangeService spevalueRangeService;
    @Autowired
    private TxtHistoryMapper txtHistoryMapper;


    /**
     * 查询特征工程指标
     *
     * @param indexsetKey 特征工程指标ID
     * @return 特征工程指标
     */
    @Override
    public TxtIndexset selectTargetsetById(String indexsetKey) {
        return txtIndexsetMapper.selectTxtIndexsetById(indexsetKey);
    }

    /**
     * 查询特征工程指标列表
     *
     * @param targetset 特征工程指标
     * @return 特征工程指标
     */
    @Override
    public List<TxtIndexset> selectTargetsetList(TxtIndexset txtIndexset) {
        return txtIndexsetMapper.selectTxtIndexsetList(txtIndexset);
    }

    /**
     * 新增特征工程指标
     *
     * @param targetset 特征工程指标
     * @return 结果
     */
    @Override
    public int insertTargetset(TxtIndexset txtIndexset) {
        txtIndexset.setCreateTime(DateUtils.getNowDate());
        return txtIndexsetMapper.insertTxtIndexset(txtIndexset);
    }

    /**
     * 修改特征工程指标
     *
     * @param targetset 特征工程指标
     * @return 结果
     */
    @Override
    public int updateTargetset(TxtIndexset txtIndexset) {
        txtIndexset.setUpdateTime(DateUtils.getNowDate());
        return txtIndexsetMapper.updateTxtIndexset(txtIndexset);
    }

    /**
     * 删除特征工程指标对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteTargetsetByIds(String ids) {
        return txtIndexsetMapper.deleteTxtIndexsetByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除特征工程指标信息
     *
     * @param indexsetKey 特征工程指标ID
     * @return 结果
     */
    public int deleteTargetsetById(String indexsetKey) {
        return txtIndexsetMapper.deleteTxtIndexsetById(indexsetKey);
    }

    @Override
    @Transactional
    public int updateRange(TxtIndexset txtIndexset) {
        int result = 0;
        TxtDataset tableName = txtDatasetMapper.selectTableNameByDatasetKey(txtIndexset.getDatasetKey());
        String englishName = txtIndexset.getEnglishName();
        StringBuffer sql = new StringBuffer();
        sql.append("select table_key,");
        sql.append(englishName);
        sql.append(" from ");
        sql.append(tableName.getSurfaceName());
        sql.append(" where dataset_key = '");
        sql.append(txtIndexset.getDatasetKey());
        sql.append(" '");
        sql.append(" AND delete_flag = 0");
        List<LinkedHashMap<String, Object>> datasetList = txtDatasetMapper.selectDatasetList(sql.toString());
        ArrayList<Float> dealList = new ArrayList<>();
        //循环list结果取 englishName 对应的值 转浮点数放在新的dealList中
        for (LinkedHashMap linkedHashMap : datasetList) {
            dealList.add(Float.valueOf(linkedHashMap.get(englishName).toString()));
        }
        //将dpList转成数组
        Float[] dealArray = new Float[dealList.size()];
        dealList.toArray(dealArray);

        float sum = 0;   //数组和
        float ave = 0;   //数组平均值
        float ave2 = 0;  //数组方差和
        float ave3 = 0;  //数组均方差
        float ave4 = 0;  //单个数方差
        Float[] fangc = new Float[dealList.size()];    //声明一个方差数组
        for (int a = 0; a < dealArray.length; a++) {
            sum += dealArray[a];
        }
        //数组求平均值
        ave = sum / dealArray.length;
        //求数组均方差
        for (int b = 0; b < dealArray.length; b++) {
            ave2 += (dealArray[b] - ave) * (dealArray[b] - ave);
            ave4 = (dealArray[b] - ave) * (dealArray[b] - ave);
            fangc[b] = ave4;     //每个值求方差放进方差数组中
        }
        ave3 = ave2 / dealArray.length;
        float min = Collections.min(Arrays.asList(fangc));   //数组中取最小方差值
        float max = Collections.max(Arrays.asList(fangc));   //数组中取最大方差值
        //如果min 于max相等 quality 算式不成立  在此判断 程序返回
        if (min - max == 0) {
            return 1;
        }
        //对dpHandleList 再次循环 取对应英文名主键及数值
        for (LinkedHashMap linkedHashMap : datasetList) {
            Float shju = Float.valueOf(linkedHashMap.get(englishName).toString());
            String tableKey = linkedHashMap.get("table_key").toString();
            //（（单个数-平均数）的平方 -均方差）/（最大方差-最小方差）
            float quality = ((shju - ave) * (shju - ave) - ave3) / (max - min);
            String fieldNameQuality = englishName.substring(englishName.lastIndexOf("_")+1) + "_quality";
            Float endValue = spevalueRangeService.searchValueByKeyValue(txtIndexset.getSpevalueTypeKey(), quality);
            StringBuffer sqlUpdate = new StringBuffer();
            sqlUpdate.append("update ");
            sqlUpdate.append( tableName.getSurfaceName() );
            sqlUpdate.append(" set ");
            sqlUpdate.append( fieldNameQuality);
            sqlUpdate.append(" =");
            sqlUpdate.append( endValue);
            sqlUpdate.append(" WHERE table_key = '");
            sqlUpdate.append(tableKey);
            sqlUpdate.append("'");
            result  = txtDatasetMapper.updatefieldNameQualityList(sqlUpdate.toString());
        }
        TxtIndexset indexsetUpdate = new TxtIndexset();
        indexsetUpdate.setIndexsetKey(txtIndexset.getIndexsetKey());
        indexsetUpdate.setDisposeFlag("3");
        indexsetUpdate.setUpdateBy(ShiroUtils.getUserId().toString());
        indexsetUpdate.setHandleBy(ShiroUtils.getUserId().toString());
        indexsetUpdate.setUpdateTime(DateUtils.getNowDate());
        txtIndexsetMapper.updateTxtIndexset(indexsetUpdate);

        TxtDataset txtDatasetUpdate = new TxtDataset();
        txtDatasetUpdate.setDatasetKey(txtIndexset.getDatasetKey());
        txtDatasetUpdate.setDisposeIcon("2");
        txtDatasetUpdate.setUpdateBy(ShiroUtils.getUserId().toString());
        txtDatasetUpdate.setAnalystBy(ShiroUtils.getUserId().toString());
        txtDatasetUpdate.setUpdateTime(DateUtils.getNowDate());
        txtDatasetMapper.updateTxtDataset(txtDatasetUpdate);

        //向记录表中添加数据
        TxtHistory txtHistory = new TxtHistory();
        txtHistory.setHistoryKey(UUID.randomUUID().toString());
        txtHistory.setDatasetKey(txtIndexset.getDatasetKey());
        txtHistory.setIndexcollectKey(txtIndexset.getIndexsetKey());
        txtHistory.setDisposeType("4");
        txtHistory.setHistoryBy(ShiroUtils.getUserId().toString());
        txtHistoryMapper.insertTxtHistory(txtHistory);
        return result;

    }

    @Override
    @Transactional
    public int editValue(TxtIndexset txtIndexset){
        int result = 0;
        //查询表中质量值属性的个数
        int qualityCount = txtDatasetMapper.selectCountByDatasetKey(txtIndexset.getDatasetKey());
        //查询
        TxtDataset tableName = txtDatasetMapper.selectTableNameByDatasetKey(txtIndexset.getDatasetKey());
        //查询TxtIndexset中EnglishName  列表
        List<TxtIndexset> indexsetEnglistNameList = txtIndexsetMapper.seleEnglishNameByDatasetKey(txtIndexset.getDatasetKey());
        //定义一个质量值名称List
        ArrayList<String> qualityNameList = new ArrayList<>();
       //遍历EnglishName  列表 将名称取_后边的字符 并把截取去的字符 + "_quality" 拼成qualityName 字符   添加到 qualityNameList  List中
        for(TxtIndexset txtIndexset1 : indexsetEnglistNameList){
            String englishName = txtIndexset1.getEnglishName();
            String qualityName = englishName.substring(englishName.lastIndexOf("_")+1) + "_quality";
            qualityNameList.add(qualityName);
        }
        System.out.println(qualityNameList);
        //list转字符串用  ， 分割
        String qualityName = String.join(", ", qualityNameList);

        StringBuffer sql = new StringBuffer();
        sql.append("select table_key,");
        sql.append( qualityName);
        sql.append(" from ");
        sql.append( tableName.getSurfaceName());
        sql.append(" where dataset_key = '");
        sql.append(txtIndexset.getDatasetKey());
        sql.append(" '");
        sql.append(" AND delete_flag = 0");
        List<LinkedHashMap<String, Object>> tabletList = txtDatasetMapper.selectDatasetList(sql.toString());
        //定义一个对象型List  存 表的主键和质量值平均值
        ArrayList<DealQuality> dealQualities = new ArrayList<>();
        for(LinkedHashMap linkedHashMap : tabletList){
            double sumQuality = 0;
            double aveLine = 0;

            for(int i =0; i < qualityCount; i++) {
                if (null != linkedHashMap.get(qualityNameList.get(i))) {
                    sumQuality += Float.valueOf(linkedHashMap.get(qualityNameList.get(i)).toString());
                }
                //quality.add(Float.valueOf(linkedHashMap.get(qualityName).toString()));
            }

            //将平均数作为计算特征值的数
            aveLine = sumQuality / qualityCount;
            DealQuality dealQuality = new DealQuality();
            dealQuality.setAveLine(aveLine);
            dealQuality.setTableKey(linkedHashMap.get("table_key").toString());
            dealQualities.add(dealQuality);
        }

        double sum = 0;                   //定义一个和sum
        double ave = 0;   //数组平均值
        double ave2 = 0;  //数组方差和
        double ave3 = 0;  //数组均方差
        double ave4 = 0;  //单个数方差

        for(DealQuality dealQuality:dealQualities){
            sum+=dealQuality.getAveLine();
        }
        ave = sum/dealQualities.size();

        Double[] fangc = new Double[dealQualities.size()];    //声明一个方差数组

        for(int i = 0;i<dealQualities.size();i++){
            System.out.println(dealQualities.get(i).getAveLine());
            ave2 += (dealQualities.get(i).getAveLine() - ave) * (dealQualities.get(i).getAveLine() - ave);
            ave4 = (dealQualities.get(i).getAveLine() - ave) * (dealQualities.get(i).getAveLine() - ave);
            fangc[i] = ave4;     //每个值求方差放进方差数组中
        }

        ave3 = ave2/dealQualities.size();              //数组均方差
        double min = Collections.min(Arrays.asList(fangc));   //数组中取最小方差值
        double max = Collections.max(Arrays.asList(fangc));   //数组中取最大方差值
        //如果min 于max相等 quality 算式不成立  在此判断 程序返回
//        if (min - max == 0 ) {
//            return 1;
//        }
        for(DealQuality dealQuality : dealQualities){
            String tableKey = dealQuality.getTableKey();
            //（（单个数-平均数）的平方 -均方差）/（最大方差-最小方差）
            Double specialValue = 1.0d;

            if ((max - min) == 0) {
                specialValue =  ((dealQuality.getAveLine()- ave)*(dealQuality.getAveLine()- ave) -ave3);
            } else {
                specialValue =  ((dealQuality.getAveLine()- ave)*(dealQuality.getAveLine()- ave) -ave3)/(max-min);
            }

            //特征值
            Double endValue = spevalueRangeService.searchValueByKeySpecialVanue(txtIndexset.getSpevalueTypeKey(),specialValue);
            //向表中添加特征值  更新处理标志
            StringBuffer sqlUpdate = new StringBuffer();
            sqlUpdate.append("update ");
            sqlUpdate.append( tableName.getSurfaceName() );
            sqlUpdate.append(" set eigan_value = ");
            sqlUpdate.append( endValue);
            sqlUpdate.append(" WHERE table_key = '");
            sqlUpdate.append(tableKey);
            sqlUpdate.append("'");
            txtDatasetMapper.updateEiganValue(sqlUpdate.toString());
        }

        //更新indexset中处理标志为4
        List<TxtIndexset> txtIndexsets = txtIndexsetMapper.selectTxtIndexsetkeyByDatasetKey(txtIndexset.getDatasetKey());
        for(TxtIndexset txtIndexset1:txtIndexsets){
            TxtIndexset indexsetUpdate = new TxtIndexset();
            indexsetUpdate.setIndexsetKey(txtIndexset1.getIndexsetKey());
            indexsetUpdate.setDisposeFlag("4");
            indexsetUpdate.setUpdateBy(ShiroUtils.getUserId().toString());
            indexsetUpdate.setHandleBy(ShiroUtils.getUserId().toString());
            indexsetUpdate.setUpdateTime(DateUtils.getNowDate());
            txtIndexsetMapper.updateTxtIndexset(indexsetUpdate);

            TxtHistory txtHistory = new TxtHistory();
            txtHistory.setHistoryKey(UUID.randomUUID().toString());
            txtHistory.setDatasetKey(txtIndexset.getDatasetKey());
            txtHistory.setIndexcollectKey(txtIndexset1.getIndexsetKey());
            txtHistory.setDisposeType("5");
            txtHistory.setHistoryBy(ShiroUtils.getUserId().toString());
            txtHistoryMapper.insertTxtHistory(txtHistory);
        }

        //更新dataset 处理标志  为4
        TxtDataset txtDatasetUpdate = new TxtDataset();
        txtDatasetUpdate.setDatasetKey(txtIndexset.getDatasetKey());
        txtDatasetUpdate.setDisposeIcon("4");
        txtDatasetUpdate.setUpdateBy(ShiroUtils.getUserId().toString());
        txtDatasetUpdate.setUpdateTime(DateUtils.getNowDate());
        txtDatasetUpdate.setAnalystBy(ShiroUtils.getUserId().toString());
        result = txtDatasetMapper.updateTxtDataset(txtDatasetUpdate);

        //向记录表中添加数据

        return  result;
    }
}
